package uy.com.dino.samefile.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Order;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public abstract class DaoHibernateBase<T, Key extends Serializable> extends
		HibernateDaoSupport implements Dao<T, Key> {

	private Class<T> persistentClass;

	@SuppressWarnings("unchecked")
	public DaoHibernateBase() {
		this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	protected Class<T> getPersistentClass() {
		return persistentClass;
	}

	public void update(T obj) {
		getHibernateTemplate().update(obj);
	}

	public void insertOrUpdate(T obj) {
		getHibernateTemplate().saveOrUpdate(obj);
	}

	public void updateCollection(Collection<T> collection) {
		getHibernateTemplate().saveOrUpdateAll(collection);
	}

	@SuppressWarnings("unchecked")
	public List<T> consultAll() {
		return getHibernateTemplate().loadAll(getPersistentClass());
	}

	@SuppressWarnings("unchecked")
	public List<T> consultAllAsc(String attribute) {
		DetachedCriteria criteria = DetachedCriteria
				.forClass(getPersistentClass());
		criteria.addOrder(Order.asc(attribute));

		List<T> result = getHibernateTemplate().findByCriteria(criteria);

		return result;
	}

	public void delete(T obj) {
		getHibernateTemplate().delete(obj);
	}

	public void deleteAll(Collection<T> colecction) {
		getHibernateTemplate().deleteAll(colecction);
	}

	public void init(T obj) {
		getHibernateTemplate().initialize(obj);
	}

	public Serializable insert(T obj) {
		return this.getHibernateTemplate().save(obj);
	}

	@SuppressWarnings("unchecked")
	public List<T> searchByExample(T exampleObject,
			String... notIncludedProperties) {
		DetachedCriteria criteria = DetachedCriteria.forClass(exampleObject
				.getClass());
		Example example = Example.create(exampleObject);
		for (String property : notIncludedProperties) {
			example.excludeProperty(property);
		}
		example.excludeZeroes();
		criteria.add(example);
		List<T> resultado = getHibernateTemplate().findByCriteria(criteria);

		return resultado;
	}

	@SuppressWarnings("unchecked")
	public T searchById(Key key) {
		return (T) getHibernateTemplate().get(getPersistentClass(), key);
	}
}
